package com.chouren.goandroid.http.request;

import java.io.File;
import java.io.InputStream;
import java.util.LinkedHashMap;

import com.chouren.goandroid.http.client.HttpClientConfig;
import com.chouren.goandroid.http.client.HttpMethod;
import com.chouren.goandroid.http.parser.DataParser;
import com.chouren.goandroid.http.request.param.HttpParam;
import com.chouren.goandroid.http.request.param.RequestParams.FileParam;
import com.chouren.goandroid.http.request.param.RequestParams.InputStreamParam;

public class Request {
	private LinkedHashMap<String, String> headers;
	private HttpParam paramModel;
	private LinkedHashMap<String, String> paramsDefault;
	private LinkedHashMap<String, InputStreamParam> paramsStream;
	private LinkedHashMap<String, FileParam> paramsFile;
	private HttpMethod method;
	private String url;
	private String charSet = HttpClientConfig.DEFAULT_CHARSET;
	private int retryMaxTimes = HttpClientConfig.DEFAULT_MAX_RETRY_TIMES;
	private DataParser<?> dataParser;
	protected Abortable abort;

	public Request(String url) {
		this(url, null);
	}
	
	public Request(String url, DataParser<?> dataParser) {
		this(url, null, dataParser);
	}
	
	public Request(String url, HttpParam httpParam, DataParser<?> dataParser) {
		this(url, httpParam, HttpMethod.Get, dataParser);
		if (url == null) throw new RuntimeException("Url Cannot be Null.");
	}
	
	public Request(String url, HttpParam paramModel, HttpMethod method, DataParser<?> dataParser) {
		this.url = url;
		this.paramModel = paramModel;
		this.method = method;
		this.dataParser = dataParser;
	}
	
	public Request addHeader(String key, String value) {
		if(value != null) {
			if(headers == null) {
				headers = new LinkedHashMap<String, String>();
			}
			headers.put(key, value);
		}
		return this;
	}
	
	public Request addParam(String key, String value) {
		if(key != null && value != null) {
			if(paramsDefault == null) {
				paramsDefault = new LinkedHashMap<String, String>();
			}
			paramsDefault.put(key, value);
		}
		return this;
	}
	
	public Request addParam(String key, File file, String contentType) {
		if(key != null && file != null) {
			if(paramsFile == null) {
				paramsFile = new LinkedHashMap<String, FileParam>();
			}
			paramsFile.put(key, new FileParam(file, contentType));
		}
		return this;
	}
	
	public Request addParam(String key, InputStream paramStream, String streamName, String contentType) {
		if (paramStream != null) {
			if (paramsStream == null) {
				paramsStream = new LinkedHashMap<String, InputStreamParam>();
			}
			paramsStream.put(key, new InputStreamParam(paramStream, streamName, contentType));
		}
		return this;
	}
	
	public static interface Abortable {
		public void abort();
	}
	
	public Request setAbort(Abortable abort) {
		this.abort = abort;
		return this;
	}
	
	public Request setMethod(HttpMethod method) {
		this.method = method;
		return this;
	}
	
	public Request setDataParser(DataParser<?> dataParser) {
		this.dataParser = dataParser;
		return this;
	}

	public DataParser<?> getDataParser() {
		return dataParser;
	}

	public LinkedHashMap<String, String> getParamsDefault() {
		return paramsDefault;
	}

	public LinkedHashMap<String, InputStreamParam> getParamsStream() {
		return paramsStream;
	}

	public LinkedHashMap<String, FileParam> getParamsFile() {
		return paramsFile;
	}

	public String getUrl() {
		return url;
	}

	public HttpMethod getMethod() {
		return method;
	}

	public LinkedHashMap<String, String> getHeaders() {
		return headers;
	}

	public int getRetryMaxTimes() {
		return retryMaxTimes;
	}

	public String getCharSet() {
		return charSet;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public HttpParam getParamModel() {
		return paramModel;
	}

	public void setParamModel(HttpParam paramModel) {
		this.paramModel = paramModel;
	}
	
}
